package BNS.plumbing;

import java.awt.Point;
import java.io.PrintStream;
import java.io.Serializable;
import java.rmi.RemoteException;
import java.util.Hashtable;
import java.util.Vector;

import BNS.graphs.Node;


/** <p>This is a utility class that implements BNSGameController, but
is used only to cause clients to do nearly nothing while they wait until the 
supervisor is ready to let them play a game. The one function it does
support is the relaying of incidental messages to the clients.</p>

<p>TODO: Why is this not a subclass of BNSGameController?</p>

<p>The counterpart class in the client machine is an implementation of 
BNSPersona known as WaitingPersona. See below.</p> */
public class WaitingGame extends BNSGameController {
  /**
   * 
   */
  private static final long serialVersionUID = 1L;
  private static final String WAITING_STRING="Waiting...\n\nPlease do not touch" +
  		" anything until instructed to do so!\n\n\nThank you, enjoy the experiment!!";
	//private boolean running=true;	// TODO: remove
	private Vector<String> msgs;
	private Hashtable<Integer,Integer> track;
	
	public WaitingGame() throws RemoteException {
		super(0);
		msgs= new Vector<String>(100);
		track= new Hashtable<Integer,Integer>(200);
		}
	
	/** Empties the queue of messages to send. */
	public void clear() { msgs.clear(); track.clear(); }
	
	/** Retains one message that will be relayed to the client when getUpdate() 
		is the next polled. */
	public void add(String m) { msgs.add(m); }
	public int cycleTime() { return 1000; }		// TODO: remove
//	public int getCycleTime() { return 1000; }	// TODO: 	/** TODO: eliminate */
	//public void stop() { /*running=false;*/ }	// TODO: remove
	
	public void init(Manager mgr, Point locn, PrintStream sessLog, PrintStream gameLog) {
//		super(mgr, locn, sessionLog, gameLog);
		gameValue= "perpetual";
		}

	public String getTitle() { return "WaitingGame"; }
	
	/** Called by the client (see BNSGameController) to see if there are any messages.
		This method returns at most one message from the queue that is being filled by add(),
		and marks it as no longer in need of being sent.
		@return a String, presumably of interest to the waiting player. 
		*/
	public Serializable getUpdate(int clientID) {
		Integer key= new Integer(clientID);
		Integer o= track.get(key);
		int last= 0;
		if (o!=null) last= o;
		//System.err.println("client "+clientID+" last message number "+last);
		if (last==msgs.size()) return "";
		String msg= msgs.elementAt(last);
		track.put(key,new Integer(last+1));
		return msg;
		}
	
	public BNSPersona getPersona(ClientLiaison client, Node node) {
		String msg;
		if (client==null) msg= ("Client Waiting");
		else msg= (WAITING_STRING);
		//else msg= ("Waiting, Client #"+ client.clientID);
//		System.err.println("created Wait persona for "+clientID +": "+ msg);
		return new TextPersona(msg);
		}
	
	public boolean alter(ClientLiaison client, Serializable changeObj) { return false; }
	
	public float getPayoff(int clientID, int time) { return 0; }
	
	public int getSize() { return 0; }	// meaningless, but required by interface
	} // EOC WaitingGame
